<?php
namespace app\api\services;

use app\api\cache\CarefreeCache;
use app\api\cache\Marketing;
use app\api\consDir\CommunityConst;
use app\api\consDir\ErrorConst;
use app\api\consDir\OrderPrefixConst;
use app\api\consDir\SandConst;
use app\common\libs\Singleton;
use app\common\models\Carefree\CarefreeMemberFinance;
use app\common\models\Carefree\CarefreeOrder;
use app\common\models\Carefree\CarefreeOrderExpress;
use app\common\models\Carefree\CarefreeOrderGoods;
use app\common\models\Carefree\CarefreeProfitPoolLog;
use app\common\models\Carefree\CarefreeRedAmountLog;
use app\common\models\Community\Community;
use app\common\models\Community\CommunityUser;
use app\common\models\Member\Member;
use app\common\models\Member\MemberGxzLog;
use app\common\models\Order\Order;
use app\common\models\Order\OrderAddress;
use app\common\models\Order\OrderExpress;
use app\common\models\Order\OrderGoods;
use app\common\models\Order\OrderPay;
use app\common\models\Order\OrderShop;
use app\common\models\Order\Postage;
use app\common\models\Shop\GoodsSku;
use app\common\models\Shop\Shop;
use app\common\utils\CommonUtil;
use think\Exception;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Log;

class CarefreeOrderService
{
    use Singleton;

    public function getOrderOrderSumByShopId($shopId): float
    {
        $where = [
            ['shop_id', '=', $shopId],
        ];
        return OrderShop::getInstance()->where($where)->sum('sell_price');
    }

    public function getOrderCountByShopId($shopId): int
    {
        $where = [
            ['shop_id', '=', $shopId],
        ];
        return OrderShop::getInstance()->where($where)->count('id');
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     */
    public function taskOrder($order): bool
    {
        $where = [
            ['order_no','=', $order['orderNo']],
        ];
        $goodsOrder = CarefreeOrderGoods::getInstance()->where($where)->select();
        if (empty($goodsOrder)) {
            return false;
        }
        $orderNo = $order['orderNo'];
        CarefreeOrder::getInstance()->startTrans();
        try {
            $update = [
                'status'  => 3, //已收货
                'task_at' => date('Y-m-d H:i:s'),
            ];

            //修改主单状态
            CarefreeOrder::getInstance()->where($where)->update($update);
            CarefreeOrderGoods::getInstance()->where($where)->update($update);
        } catch (\Exception $e) {
            Log::error($e->getMessage());
            CarefreeOrder::getInstance()->rollback();
            return false;
        }
        CarefreeOrder::getInstance()->commit();
        return true;
    }

    public function orderExpress($orderNo, $goodsId): array
    {
        $where = [
            'order_no' => $orderNo,
            'goods_id' => $goodsId,
        ];
        $express = OrderExpress::getInstance()->where($where)->find();

        if (empty($express)) {
            return [];
        }
        // $express['expressNo'] = 'YT8953807276859';
        // $express['expressName'] = '韵达快递';
        $data = ExpressService::getInstance()->query([
            // 'expressCode' => 'yuantong',
            'expressNo' => $express['expressNo'],
        ]);

        return [
            'expressNo'   => $express['expressNo'],
            'expressName' => $express['expressName'] ?? '',
            'expressCode' => $data['com'] ?? '',
            'expressList' => $data['data'] ?? [],
        ];
    }

    public function getOrderShopInfo($orderNo): array
    {
        $where = [
            'order_no' => $orderNo,
        ];
        $field     = 'shop_id,shop_name,pay_price,postage,sale,order_no';
        $orderShop = OrderShop::getInstance()->where($where)->field($field)->select();
        $orderShop = empty($orderShop) ? [] : $orderShop->toArray();
        if (empty($orderShop)) {
            return [];
        }
        foreach ($orderShop as &$v) {
            $where = [
                ['order_no', '=', $v['orderNo']],
                ['shop_id', '=', $v['shopId']],
            ];
            $field          = 'goods_id,goods_img,goods_title,id,sku_title,is_freight_insurance,is_seven,quantity,sell_price,status';
            $v['goodsInfo'] = OrderGoods::getInstance()->where($where)->field($field)->select()->toArray();
            //读取店铺信息
            $v['shop_logo']         = "";
            $v['shop_business_img'] = "";
            $v['kf_phone']          = "";
            if ($v['shopId'] != 0) {
                $shopWhere              = ['id' => (int) $v['shopId']];
                $shopInfos              = Shop::getInstance()->where($shopWhere)->find();
                $v['shop_logo']         = $shopInfos['shop_logo'];
                $v['shop_business_img'] = $shopInfos['shop_business_img'];
                $v['kf_phone']          = $shopInfos['kf_phone'];
            }
        }

        return $orderShop;
    }

    public function getOrderAddress($orderNo): array
    {
        $where = [
            'order_no' => $orderNo,
        ];
        $field   = 'province,city,country,street,comm,address,phone,real_name';
        $address = OrderAddress::getInstance()->field($field)->where($where)->find();
        return empty($address) ? [] : $address->toArray();
    }

    public function delOrder($orderInfo)
    {
        CarefreeOrder::getInstance()->startTrans();
        try {
            //修改退款状态
            $order = CarefreeOrder::getInstance()
                ->where('id', $orderInfo['id'])
                ->update(['deleted' => 1]);
            if ( ! $order) {
                return false;
            }

            /*if ($orderInfo['orderType'] != 4) {
                $orderShop = OrderShop::getInstance()
                    ->where('order_no', $orderInfo['orderNo'])
                    ->update(['deleted' => 1]);
                if ( ! $orderShop) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }*/

            $orderGoods = CarefreeOrderGoods::getInstance()
                ->where('order_no', $orderInfo['orderNo'])
                ->update(['deleted' => 1]);

            CarefreeOrder::getInstance()->commit();
            return true;

        } catch (\Exception $e) {

        }
        return false;
    }

    /**
     * @param $orderInfo
     * @return bool
     */
    public function orderRefund($orderInfo)
    {
        $where = [
            'order_no' => $orderInfo['orderNo'],
        ];
        $orderGoodsList = OrderGoods::getInstance()
            ->field(['goods_id', 'sku_id', 'quantity'])
            ->where($where)
            ->select()->toArray();

        Order::getInstance()->startTrans();
        try {
            //修改退款状态
            $order = Order::getInstance()
                ->where('id', $orderInfo['id'])
                ->update(['status' => 7, 'refund_at' => date('Y-m-d H:i:s')]);

            if ( ! $order) {
                return false;
            }

            $orderShop = OrderShop::getInstance()
                ->where('order_no', $orderInfo['orderNo'])
                ->update(['status' => 7, 'refund_at' => date('Y-m-d H:i:s')]);
            if ( ! $orderShop) {
                Order::getInstance()->rollback();
                return false;
            }

            $orderGoods = OrderGoods::getInstance()
                ->where('order_no', $orderInfo['orderNo'])
                ->update(['status' => 7, 'refund_at' => date('Y-m-d H:i:s')]);
            if ( ! $orderGoods) {
                Order::getInstance()->rollback();
                return false;
            }
            if ($orderInfo['payAmount'] > 0) {
                $msg     = '订单取消，退回余额：' . $orderInfo['payAmount'];
                $finance = MemberService::getInstance()
                    ->addFinanceLog($orderInfo['userId'], 'order_cancel', $orderInfo['payAmount'], 1, $msg);
                if ( ! $finance) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }
            if ($orderInfo['payPrice'] > 0) {
                $refund = WechatPayService::getInstance()->refund($orderInfo, $orderInfo['payPrice']);
                if ( ! $refund) {
                    Order::getInstance()->rollback();
                    return false;
                }
            }

            // 线上线下单取消订单加库存减销量
            // 1线下直付单 2线上单 3线下单 4供应链
            if (in_array($orderInfo['orderType'], [1, 2, 3])) {
                foreach ($orderGoodsList as $item) {
                    $goods_id     = $item['goodsId'];
                    $goods_sku_id = $item['skuId'];
                    \think\facade\Db::table('goods')
                        ->where('id', $goods_id)
                        ->dec('goods_sales', $item['quantity'])
                        ->inc('goods_inventory', $item['quantity'])
                        ->update();
                    if ($goods_sku_id > 0) {
                        \think\facade\Db::table('goods_sku')
                            ->where('goods_id', $goods_id)
                            ->where('id', $goods_sku_id)
                            ->dec('goods_sales', $item['quantity'])
                            ->inc('goods_inventory', $item['quantity'])
                            ->update();
                    }
                }
            }

            Order::getInstance()->commit();
            return true;

        } catch (\Exception $e) {

            Order::getInstance()->rollback();
        }
        return false;
    }

    /**
     * @param $uId
     * @param $type
     * @param $page
     * @param $pageSize
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function orderList($uId, $type, $page, $pageSize): array
    {
        //1全部 2待付款 3待发货 4待收货 5待评价 6售后
        switch ($type) {
            case 1:
                $where = [
                    ['user_id', '=', $uId],
                    ['deleted', '=', 0],
                ];
                break;
            case 2:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 0],
                    ['deleted', '=', 0],
                ];
                break;
            case 3:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 1],
                    ['deleted', '=', 0],
                ];
                break;
            case 4:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 2],
                    ['deleted', '=', 0],
                ];
                break;
            case 5:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 3],
                    ['is_comment', '=', 0],
                    ['deleted', '=', 0],
                ];
                break;
            case 10:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', '=', 10],
                    ['deleted', '=', 0],
                ];
                break;
            default:
                $where = [
                    ['user_id', '=', $uId],
                    ['status', 'in', [5, 6]],
                    ['deleted', '=', 0],
                ];
        }

        $list = CarefreeOrder::getInstance()
            ->where($where)
            ->page($page,$pageSize)
            ->field('id,status,order_no,user_id,sell_price,order_type,pay_price,postage,sale,pay_at,create_at,expire_at,is_comment')
            ->order('id desc')
            ->select();
        if (empty($list)) {
            return [];
        }
        $list = $list->toArray();

        foreach ($list as &$val) {
            $orderInfo         = CarefreeOrderGoods::getInstance()->where('order_no',$val['orderNo'])->field('is_freight_insurance,is_seven,status,quantity,sell_price,goods_id,goods_title,sku_title,goods_img')->select();
            $val['createAt']   = date('Y-m-d H:i', strtotime($val['createAt']));
            $expireTime        = strtotime($val['expireAt']) - time();
            $val['expireTime'] = max($expireTime, 0);
            $val['goodsInfo']  = empty($orderInfo) ? [] : $orderInfo->toArray();
        }
        return $list;
    }

    /**
     * 支付成功
     * @param $orderNo
     * @param string $tradeNo
     * @return bool
     */
    public function payCallback($orderNo, string $tradeNo = '',$payNo = ''): bool
    {
        $date = date('Y-m-d H:i:s');
        //判断订单类型
        $orderData = Order::getInstance()->where(['order_no' => $orderNo])->find();
        if (empty($orderData)) {
            return false;
        }
        //待发货
        $orderDate = ['status' => 1, 'pay_at' => $date, 'trade_no' => $tradeNo];
        if ($orderData['order_type'] == 1) {
            //线下直接支付订单，默认为完成状态
            $orderDate = ['status' => 4, 'pay_at' => $date, 'trade_no' => $tradeNo, 'completion_at' => $date];
        }

        //自提
        if($orderData['order_type'] == 2 && $orderData['service_id'] > 0){
            $orderDate = ['status' => 10, 'pay_at' => $date, 'trade_no' => $tradeNo];
        }
        $where = [
            'order_no' => $orderNo,
        ];
        $orderGoodsList = OrderGoods::getInstance()
            ->field(['goods_id', 'sku_id', 'quantity'])
            ->where($where)
            ->select()->toArray();
        try {
            OrderGoods::getInstance()->where($where)->update($orderDate);
            if ($orderData['order_type'] != 4) {
                OrderShop::getInstance()->where($where)->update($orderDate);
            }
            //$isDirect = ShopService::getInstance()->IsDirectByOrderNo($orderNo);
            // order_type 1线下直付单 2线上单 3线下单(有商品)  4供应链
            //线下直推分佣
            if ($orderData['order_type'] == 1) {
                $this->dividend($orderData);
                $subOrderItems = OrderShop::getInstance()->where($where)->select();
                //$price  = $orderData['sellPrice'] > 0 ? $orderData['sellPrice'] : $orderData['payPrice'];
                if ( ! empty($subOrderItems)) {
                    $msg = '线下支付订单';
                    foreach ($subOrderItems as $key => $subItem) {
                        $shopId = $subItem['shopId'];
                        $price  = $subItem['payPrice'];
                        //线下货款
                        $shop = Shop::getInstance()->where('id', $shopId)->find();
                        // 扣除让利
                        // platformFee 让利比例
                        if($orderData['order_type'] == 1){
                            $subItem['sellPrice'] =  $subItem['payPrice'];
                        }
                        $reduceMoney = bcmul($subItem['sellPrice'], $shop['platformFee'] * 0.01, 2);
                        // 线下货款 = 实付金额 - 让利金额(sellPrice * 让利比例) + 平台优惠 + 优惠折扣(用户等级优化折扣)
                        //$goodsMoney = $subItem['payPrice'] - $reduceMoney + $subItem['platformSale'] + ($subItem['discountSale'] ?? 0);
                        $goodsMoney = $subItem['payPrice'] - $reduceMoney + $subItem['platformSale'] + ($subItem['discountSale'] ?? 0);
                        $goodsMoney = bcadd($goodsMoney,0,2);
                        MemberService::getInstance()->addFinanceLog($shop['userId'], 'order_task', $goodsMoney, 2, $msg);

                        $msg = '商家货款，订单号'.$orderNo;
                        ShopService::getInstance()->payToShopSand($orderNo,$payNo,$orderData['isDirect'],$subItem['payPrice'],$goodsMoney,$shop['userId'],$orderData['payType'],$msg);


                        //商家后台积分赠送比例，是用户获得数字积分的比例，比如设置为10% ，即用户消费100 可获得10个数字积分
                        $gxzRate = OrderGoods::getInstance()->where(['order_no' => $orderNo, 'shop_id' => $shopId])->value('gxz_rate');
                        if ($gxzRate > 0) {
                            $shop['gxzRate'] = $gxzRate;
                        }
                        if ($shop['gxzRate'] > 0) {
                            $money = bcmul($price, $shop['gxzRate'] * 0.01, 4);
                            if ($money > 0) {
                                //$msg = '购买商品，赠送数字积分';
                                //MemberService::getInstance()->addFinanceLog($orderData['userId'], 'offline', $money, 6, $msg, $orderNo, 2);
                                $msg = '线下订单消费，赠送贡献值，订单号' . $orderNo;
                                MemberService::getInstance()->addFinanceLog($subItem['userId'], 'offline', $money, 7, $msg, $orderNo);
                            }
                        }
                        //加入分润池
                        $profit = bcmul($price, $shop['platformFee'] * 0.01, 4);
                        MemberService::getInstance()->profitPoolLog($subItem['userId'], $subItem['payPrice'], $orderNo, $profit, 2);
                    }
                }
            }
            if ($orderData['order_type'] == 4) {
                $orderAddress = OrderAddress::getInstance()
                    ->where('order_no', $orderData['orderNo'])
                    ->find();
                $ret = SupplyService::getInstance()->submitOrder(
                    $orderData['goodsList'],
                    $orderAddress['realName'],
                    $orderAddress['address'],
                    $orderAddress['phone'],
                    $orderData['addrPath'],
                    $orderData['orderNo']);
                Log::info('供应链下单返回参数:' . json_encode($ret, 320));
                if (empty($ret) || $ret['status'] != 200) {
                    return false;
                }
                $orderDate['supply_order_no'] = $ret['data']['orderList'][0]['orderSn'];
            }
            //线上商家 order_type线下直付单 2线上单 3线下单 4供应链
            if(in_array($orderData['order_type'],[2,3]) && $orderData['pay_type'] == 4){
                $subOrderItems = OrderShop::getInstance()->where($where)->select();
                foreach($subOrderItems as $subItem){
                    $shop = Shop::getInstance()->where('id', $subItem['shopId'])->find();

                    $reduceMoney = bcmul($subItem['sellPrice'], $shop['platformFee'] * 0.01, 2);
                    // 线上货款 = 实付金额 - 让利金额(sellPrice * 让利比例) + 平台优惠 + 优惠折扣(用户等级优化折扣)
                    //$goodsMoney = $subItem['sellPrice'] - $reduceMoney + $subItem['platformSale'] + ($subItem['discountSale'] ?? 0);
                    $goodsMoney = bcsub(bcsub($subItem['sellPrice'],$reduceMoney,2),$subItem['shopSale'],2);
                    if($orderData['isDirect'] == 1){
                        $ret = SandService::getInstance()->transferConfirm(getNo(OrderPrefixConst::TC), $payNo, $subItem['payPrice'], 'confirm', SandConst::PREFIX . $shop['userId']);
                        Log::info($orderNo . '线上商家杉德确认转账返回' . json_encode($ret, 256));
                        if (!isset($ret['resultStatus']) || $ret['resultStatus'] != 'success') {
                            Log::error(json_encode($ret,256));
                            throw new Exception($orderNo . $ret['errorDesc']);
                        }
                        //冻结金额
                        $ret = SandService::getInstance()->freeze(getNo('freeze'),$goodsMoney,$shop['userId']);
                        Log::error(json_encode($ret, 256));
                        if (isset($ret['resultStatus']) && $ret['resultStatus'] != 'success') {
                            throw new Exception($orderNo . '冻结金额' . $ret['errorDesc']);
                        }
                        $subItem->freeze_order_no = $ret['outOrderNo'];
                        $subItem->save();
                    }
                }
            }
            Order::getInstance()->where($where)->update($orderDate);



            // 线上线下单付款减库存加销量
            // 1线下直付单 2线上单 3线下单 4供应链
            if (in_array($orderData['order_type'], [1, 2, 3])) {
                foreach ($orderGoodsList as $item) {
                    $goods_id     = $item['goodsId'];
                    $goods_sku_id = $item['skuId'];
                    \think\facade\Db::table('goods')
                        ->where('id', $goods_id)
                        ->inc('goods_sales', $item['quantity'])
                        ->dec('goods_inventory', $item['quantity'])
                        ->update();
                    if ($goods_sku_id > 0) {
                        \think\facade\Db::table('goods_sku')
                            ->where('goods_id', $goods_id)
                            ->where('id', $goods_sku_id)
                            ->inc('goods_sales', $item['quantity'])
                            ->dec('goods_inventory', $item['quantity'])
                            ->update();
                    }
                }
            }
        } catch (\Exception $e) {
            Log::error($orderNo . $e->getMessage());
            return false;
        }
        return true;
    }

    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function dividend($order): bool
    {
        if (empty($order)) {
            return false;
        }

        $arr   = [1 => 'first_offline', 2 => 'first_online', 3 => 'first_offline', 4 => 'first_online'];
        $where = [
            ['user_id', '=', $order['userId']],
            ['log_type', 'in', ['first_online','first_offline']],
        ];
        $count = MemberGxzLog::getInstance()->where($where)->count();
        if ($count <= 0) {
            $nameArr = ['first_online' => '线上消费', 'first_offline' => '线下消费'];
            MemberService::getInstance()->sendNewTaskGxz($order['userId'], $arr[$order['orderType']], '第一次' . $nameArr[$arr[$order['orderType']]]);
        }

        $dividend = Marketing::getKeyData('marketing', 'dividend');
        if(empty($dividend)){
            return false;
        }
        $shopId = OrderShop::getInstance()->where('order_no', $order['orderNo'])->value('shop_id');
        if(isset($dividend['user_status']) && $dividend['user_status'] == 1){
            $price = $order['payPrice'];
            $remark = '消费金额的';
            if(isset($dividend['user_dividend_type']) && $dividend['user_dividend_type'] == 1){
                //按商家服务或产品利润
                //order_type 1线下直付单 2线上单 3线下单 4供应链
                if($order['orderType'] == 4){
                    $price = bcsub($order['sellPrice'],$order['costPrice'],2);
                }else{
                    $platformFee = Shop::getInstance()->where('id',$shopId)->value('platform_fee');
                    $price = bcmul($order['sellPrice'],$platformFee*0.01,2);
                }
                $price = bcsub($price,$order['platformSale'],2);
                $remark = '让利的';
            }

            if($price <= 0){
                return false;
            }
            //直推会员消费收益 会员消费金额的0.7%
            //$rate        = CommunityService::getInstance()->getCommunityConfig('direct_member_earnings');
            $rate        = $dividend['user_invite_rate'];
            $inviteMoney = bcmul($price, $rate * 0.01, 4);
            $member      = Member::getInstance()->where('id', $order['userId'])->find();
            if ($inviteMoney > 0 && $member['inviteId']) {
                $msg = '推广会员消费，获得直推会员消费收益，'. $remark . $rate . '%';
                MemberService::getInstance()->addFinanceLog($member['inviteId'], 'direct_member_earnings', $inviteMoney, 5, $msg, $order['orderNo'], 1, 2);
            }

            //社区会员消费收益
            $commId = Community::getInstance()->where('comm_id', $member['commId'])->value('id');
            $where  = [
                ['community_id', '=', $commId],
                ['community_status', 'in', [CommunityConst::CHECK_STATUS, CommunityConst::PERMANENT_STATUS]],
            ];
            $community = CommunityUser::getInstance()->where($where)->find();
            if ($community && $community['userId']) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('community_member_earnings');
                $rate = $dividend['user_community_partner_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = '推广会员消费，获得社区会员消费收益，'. $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($community['userId'], 'community_member_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }

            //服务商收益
            if(isset($dividend['user_partner_status']) && $dividend['user_partner_status'] == 1){
                $partner = MemberService::getInstance()->getMyPartnerInfo($order['userId']);
                if ($partner) {
                    if ($partner['partnerId']) {
                        $rate  = $dividend['user_partner_rate'];
                        $msg   = '推广会员消费，获得服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                        $bonus = bcmul($price, $rate*0.01, 4);
                        MemberService::getInstance()->addFinanceLog($partner['partnerId'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }
            }

            //平级服务商
            if(isset($dividend['user_ping_partner_status']) && $dividend['user_ping_partner_status'] == 1){
                $userPingMember = Member::getInstance()->where('id',$order['userId'])->find();
                $myPartner = MemberService::getInstance()->getMyPartner($userPingMember);
                if ($myPartner) {
                    if ($myPartner['id']) {
                        $rate  = $dividend['user_ping_partner_rate'];
                        $msg   = '推广会员消费，获得平级服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                        $bonus = bcmul($price, $rate*0.01, 4);
                        MemberService::getInstance()->addFinanceLog($myPartner['id'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }
            }

            //区域（省/市/区县）会员消费收益
            $partnerInfo = MemberService::getInstance()->getAgencyArr($member['provinceId'], $member['cityId'], $member['countryId'], $member['streetId']);
            if ($partnerInfo['provinceUid'] > 0) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('member_province_earnings');
                $rate = $dividend['user_province_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = "推广会员消费，获得区域（" . $partnerInfo['provinceName'] . "）会员消费收益，". $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($partnerInfo['provinceUid'], 'province_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }

            if ($partnerInfo['cityUid'] > 0) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('member_city_earnings');
                $rate = $dividend['user_city_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = "推广会员消费，获得区域（" . $partnerInfo['cityName'] . "）会员消费收益，". $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($partnerInfo['cityUid'], 'city_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }

            if ($partnerInfo['countryUid'] > 0) {
                //$rate  = CommunityService::getInstance()->getCommunityConfig('member_area_earnings');
                $rate = $dividend['user_area_rate'];
                $bonus = bcmul($price, $rate * 0.01, 4);
                if ($bonus > 0) {
                    $msg = "推广会员消费，获得区域（" . $partnerInfo['countryName'] . "）会员消费收益，" . $remark . $rate . '%';
                    MemberService::getInstance()->addFinanceLog($partnerInfo['countryUid'], 'area_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                }
            }
        }

        if(isset($dividend['shop_status']) && $dividend['shop_status'] == 1){
            //$shopId = OrderShop::getInstance()->where('order_no', $order['orderNo'])->value('shop_id');
            if ($shopId) {
                $platformFee = Shop::getInstance()->where('id', $shopId)->value('platform_fee');
                //让利部分
                $money = bcmul($order['sellPrice'], $platformFee * 0.01, 4);
                $money = bcsub($money,$order['platformSale'],2);
                $remark = '让利的';
                if(isset($dividend['shop_dividend_type']) && $dividend['shop_dividend_type'] == 0){
                    $money = $order['payPrice'];
                    $remark = '消费金额的';
                }
                if($money <= 0){
                    return false;
                }

                //直推商家让利收益 商家营业中让利部分3%
                $shop     = Shop::getInstance()->where('id', $shopId)->find();
                $inviteId = Member::getInstance()->where('id', $shop['userId'])->value('invite_id');
                if ($inviteId) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('direct_shop_earnings');
                    $rate = $dividend['shop_invite_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = '推广商家，获得直推商家让利收益，让利的' . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($inviteId, 'direct_shop_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                //社区商家让利收益
                $commId = Community::getInstance()->where('comm_id', $shop['commId'])->value('id');
                $where  = [
                    ['community_id', '=', $commId],
                    ['community_status', 'in', [CommunityConst::CHECK_STATUS, CommunityConst::PERMANENT_STATUS]],
                ];
                $community = CommunityUser::getInstance()->where($where)->find();

                if ($community && $community['userId']) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('community_shop_earnings');
                    $rate = $dividend['shop_community_partner_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = '推广商家，获得社区会员消费收益，' . $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($community['userId'], 'community_shop_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                //服务商收益
                if(isset($dividend['shop_partner_status']) && $dividend['shop_partner_status'] == 1){
                    $partner = MemberService::getInstance()->getMyPartnerInfo($shop['userId']);
                    if ($partner) {
                        if ($partner['partnerId']) {
                            $rate  = $dividend['shop_partner_rate'];
                            $msg   = '推广商家，获得服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                            $bonus = bcmul($money, $rate*0.01, 4);
                            MemberService::getInstance()->addFinanceLog($partner['partnerId'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                        }
                    }
                }

                //平级服务商
                if(isset($dividend['shop_ping_partner_status']) && $dividend['shop_ping_partner_status'] == 1){
                    $shopPingMember = Member::getInstance()->where('id',$shop['userId'])->find();
                    $myPartner = MemberService::getInstance()->getMyPartner($shopPingMember);
                    if ($myPartner) {
                        if ($myPartner['id']) {
                            $rate  = $dividend['shop_ping_partner_rate'];
                            $msg   = '推广商家，获得平级服务商收益，收益比例' . $rate . '%，订单' . $order['orderNo'];
                            $bonus = bcmul($money, $rate*0.01, 4);
                            MemberService::getInstance()->addFinanceLog($myPartner['id'], 'spread_service_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                        }
                    }
                }

                //区域（省/市/区县）商家让利收益
                $shopPartnerInfo = MemberService::getInstance()->getAgencyArr($shop['provinceId'], $shop['cityId'], $shop['countryId'], $shop['streetId']);
                if ($shopPartnerInfo['provinceUid'] > 0) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('shop_province_earnings');
                    $rate = $dividend['shop_province_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = "推广商家，获得区域（" . $shopPartnerInfo['provinceName'] . "）会员消费收益，". $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($shopPartnerInfo['provinceUid'], 'shop_province_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                if ($shopPartnerInfo['cityUid'] > 0) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('shop_city_earnings');
                    $rate = $dividend['shop_city_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = "推广商家，获得区域（" . $shopPartnerInfo['cityName'] . "）会员消费收益，". $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($shopPartnerInfo['cityUid'], 'shop_city_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }

                if ($shopPartnerInfo['countryUid'] > 0) {
                    //$rate  = CommunityService::getInstance()->getCommunityConfig('shop_area_earnings');
                    $rate = $dividend['shop_area_rate'];
                    $bonus = bcmul($money, $rate * 0.01, 4);
                    if ($bonus > 0) {
                        $msg = "推广商家，获得区域（" . $shopPartnerInfo['countryName'] . "）会员消费收益，". $remark . $rate . '%';
                        MemberService::getInstance()->addFinanceLog($shopPartnerInfo['countryUid'], 'shop_area_earnings', $bonus, 5, $msg, $order['orderNo'], 1, 2);
                    }
                }
            }
        }

        return true;
    }

    public function createOrder($goods, $sku, $num, $addressInfo, $orderNo, $userNote,$userId, $couponId = 0, $deduction = 0): bool
    {
        $payPrice = bcmul($sku['sell_price'],$num,2);
        $sellPrice = $payPrice;
        if($deduction > 0){
            $payPrice = bcsub($payPrice,$deduction,2);
        }
        CarefreeOrder::getInstance()->startTrans();
        try {
            $data = [
                'user_id' => $userId,
                'order_no' => $orderNo,
                'cost_price' => bcmul($sku['cost_price'],$num,2),
                'sell_price' => $sellPrice,
                'pay_price' => $payPrice,
                'user_note' => $userNote,
                'deduction' => $deduction,
                'expire_at' => date('Y-m-d H:i:s', strtotime('+5 minutes')),
            ];
            $order = CarefreeOrder::getInstance()->insert($data);
            if ( ! $order) {
                return false;
            }
            if ( ! empty($addressInfo)) {
                $addressInfo['order_no'] = $orderNo;
                $address                 = OrderAddress::getInstance()->insert($addressInfo);
                if ( ! $address) {
                    CarefreeOrder::getInstance()->rollback();
                    return false;
                }
            }

            unset($addressInfo['id']);
            $addressInfo['member_id'] = $userId;
            $addressInfo['create_at'] = date('Y-m-d H:i:s');
            CarefreeOrderExpress::getInstance()->insert($addressInfo);

            $data = [
                'order_no' => $orderNo,
                'goods_id' => $goods['id'],
                'sku_id' => $sku['id'],
                'cost_price' => $sku['cost_price'],
                'sell_price' => $sku['sell_price'],
                'quantity' => $num,
                'user_id' => $userId,
                'goods_img' => $goods['goods_img'],
                'goods_title' => $goods['goods_title'],
                'sku_title' => $sku['sku_title'],
                'pay_price' => bcmul($sku['sell_price'],$num,2),
            ];
            $orderGoods = CarefreeOrderGoods::getInstance()->strict(false)->insert($data);
            if ( ! $orderGoods) {
                CarefreeOrder::getInstance()->rollback();
                return false;
            }

            if ( ! empty($couponId)) {
                CouponService::getInstance()->updateCouponInfo($couponId);
            }

        } catch (\Exception $e) {
            CarefreeOrder::getInstance()->rollback();
            return false;
        }
        CarefreeOrder::getInstance()->commit();
        return true;
    }


    /**
     * @throws ModelNotFoundException
     * @throws DataNotFoundException
     * @throws DbException
     */
    public function getOrderInfo($orderNo, $uid): array
    {
        $where = [
            ['order_no', '=', $orderNo],
            ['user_id', '=', $uid],
        ];
        $order = CarefreeOrder::getInstance()
            ->where($where)
            ->find();
        return empty($order) ? [] : $order->toArray();
    }

    public function getPostAge($spId, $quantity, $sellPrice)
    {
        $spInfo = $this->getPost($spId);
        switch ($spInfo['type']) {
            case 1:
                return 0;
            case 2:
                $allPrice = bcmul($quantity, $sellPrice, 2);
                if ($allPrice >= $spInfo['quota']) {
                    return 0;
                } else {
                    return $spInfo['price'];
                }
            case 3:
                return bcmul($quantity, $spInfo['price'], 2);
        }
        return 0;
    }

    public function getPost($spId): array
    {
        $where = [
            ['id', '=', $spId],
            ['deleted', '=', 0],
        ];
        $spInfo = Postage::getInstance()->where($where)->find();
        return empty($spInfo) ? [] : $spInfo->toArray();
    }

}
